package thread;

import java.util.concurrent.*;

/**
 * @author: kejl
 * @create: 2020-09-25 13:10
 */
public class Test {

    @org.junit.jupiter.api.Test
    void createThread() throws ExecutionException, InterruptedException {
        //Thread 去创建
        Thread thread = new Thread(new Tthread());
        thread.setName("继承的方式启动");
        thread.start();

        //Runnable去创建
        Thread rhread = new Thread(new Rthread(),"222");
        rhread.start();

        Callable<String> callable  =new MyThread();

        //callable 去创建线程
        FutureTask<String> futureTask=new FutureTask<>(callable);

        Thread mThread=new Thread(futureTask);
        Thread mThread2=new Thread(futureTask);
        Thread mThread3=new Thread(futureTask);
		mThread.setName("hhh");
        mThread.start();
        mThread2.start();
        mThread3.start();
        System.out.println(futureTask.get());

        //线程池创建：
        //创建一个可缓存线程池 Executors.newCacheThreadPool()
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            try {
                //sleep可明显看到使用的是线程池里面以前的线程，没有创建新的线程
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //内部执行线程内容
            cachedThreadPool.execute(new Runnable() {
                public void run() {
                    //打印正在执行的缓存线程信息
                    System.out.println(Thread.currentThread().getName()+"正在被执行");
                }
            });
        }

        //创建一个可重用固定个数的线程池 Executors.newFixedThreadPool(int n)
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            fixedThreadPool.execute(new Runnable() {
                public void run() {
                    try {
                        //打印正在执行的缓存线程信息
                        System.out.println(Thread.currentThread().getName()+"正在被执行");
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        //创建一个定长线程池，支持定时及周期性任务执行——定期执行
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        //延迟1秒后每3秒执行一次
        scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
            public void run() {
                System.out.println("延迟1秒后每3秒执行一次");
            }
        }, 1, 3, TimeUnit.SECONDS);

        //创建一个单线程化的线程池
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            singleThreadExecutor.execute(new Runnable() {
                public void run() {
                    try {
                        //结果依次输出，相当于顺序执行各个任务
                        System.out.println(Thread.currentThread().getName()+"正在被执行,打印的值是:"+index);
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        //可以使用 submit进行多线程的值返回 excite和submit的
        //1、接收的参数不一样
        //2、submit有返回值，而execute没有
        //3.submit方便Exception处理

        ExecutorService pool = Executors.newFixedThreadPool(2);

        /**
         * execute(Runnable x) 没有返回值。可以执行任务，但无法判断任务是否成功完成。
         */
        pool.execute(new RunnableTest("Task1"));

        /**
         * submit(Runnable x) 返回一个future。可以用这个future来判断任务是否成功完成。请看下面：
         */
        Future future = pool.submit(new RunnableTest("Task2"));

        try {
            if(future.get()==null){//如果Future's get返回null，任务完成
                System.out.println("任务完成");
            }
        } catch (InterruptedException e) {
        } catch (ExecutionException e) {
            //否则我们可以看看任务失败的原因是什么
            System.out.println(e.getCause().getMessage());
        }





    }

    class Tthread extends Thread{

        public void run(){
            System.out.println("继承线程启动了");
        }

    }


     class Rthread implements Runnable{

         @Override
         public void run() {
             System.out.println("实现runnable线程启动了");
         }
     }

     class MyThread implements Callable<String> {

         private int count = 20;

         @Override
         public String call() throws Exception {
             for (int i = count; i > 0; i--) {
//			Thread.yield();
                 System.out.println(Thread.currentThread().getName()+"当前票数：" + i);
             }
             return "sale out";

         }
     }

     class RunnableTest implements Runnable {

        private String taskName;

        public RunnableTest(final String taskName) {
            this.taskName = taskName;
        }

        @Override
        public void run() {
            System.out.println("Inside "+taskName);
            throw new RuntimeException("RuntimeException from inside " + taskName);
        }

    }






}
